/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.apache.skywalking.oap.server.core.register;

import lombok.*;
import org.apache.skywalking.oap.server.core.remote.data.StreamData;
import org.apache.skywalking.oap.server.core.storage.StorageData;
import org.apache.skywalking.oap.server.core.storage.annotation.Column;

/**
 * @author peng-yongsheng
 */
// 抽象了服务注册、服务实例注册、EndpointName（以及 NetworkAddress）同步 三个过程中产生的数据。
// 每一种 RegisterSource 数据都对应一个 Cache，通过 Cache 的方式提高查询性能，每个 Cache 底层都关联了一个 Cache DAO 接口实现。
// RegisterSource 的四个实现类：
//      1、ServiceInventory 抽象了服务注册的数据。
//      2、ServiceInstanceInventory 抽象了服务实例注册的数据。
//      3、EndpointInventory 抽象了 EndpointName 同步的数据。
//      4、NetworkAddressInventory 抽象了 NetworkAddress 同步的数据。
// Inventory：详细目录，清单
public abstract class RegisterSource extends StreamData implements StorageData {

    public static final String SEQUENCE = "sequence";
    public static final String REGISTER_TIME = "register_time";
    public static final String HEARTBEAT_TIME = "heartbeat_time";

    // 上述三个过程中的数据都会产生一个全局唯一的 ID，该全局 ID 就保存在该字段中
    // 生成唯一ID，在服务注册过程中，即为ServiceId
    @Getter @Setter @Column(columnName = SEQUENCE) private int sequence;
    // 第一次注册（或同步）时的时间戳
    @Getter @Setter @Column(columnName = REGISTER_TIME) private long registerTime;
    // 最近一次心跳时间戳
    @Getter @Setter @Column(columnName = HEARTBEAT_TIME) private long heartbeatTime;

    public boolean combine(RegisterSource registerSource) {
        if (heartbeatTime < registerSource.getHeartbeatTime()) {
            heartbeatTime = registerSource.getHeartbeatTime();
            return true;
        } else {
            return false;
        }
    }
}
